package 中等.搜索.广度优先搜索;


import java.util.ArrayDeque;
import java.util.Deque;

/**
 * 给你一个 n x n 的二进制矩阵 grid 中，返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径，返回 -1 。
 * <p>
 * 二进制矩阵中的 畅通路径 是一条从 左上角 单元格（即，(0, 0)）到 右下角 单元格（即，(n - 1, n - 1)）的路径，该路径同时满足下述要求：
 * <p>
 * 路径途经的所有单元格都的值都是 0 。
 * 路径中所有相邻的单元格应当在 8 个方向之一 上连通（即，相邻两单元之间彼此不同且共享一条边或者一个角）。
 * 畅通路径的长度 是该路径途经的单元格总数。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/shortest-path-in-binary-matrix
 */
public class 二进制矩阵中的最短路径_1091 {

    public static void main(String[] args) {

        int[][] grids = {{0, 1, 1}, {1, 0, 1}, {1, 1, 0}};
        System.out.println(shortestPathBinaryMatrixt(grids));
    }


    public static int shortestPathBinaryMatrixt(int[][] grid) {

        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return -1;
        }
        //第一格不畅通直接返回
        if (grid[0][0] == 1) {
            return -1;
        }
        //定义方向
        //上:rows-1,columns不变,左上，右上，左，右,下,右下，左下
        int[][] direction = {{-1, 0}, {-1, -1}, {-1, 1}, {0, -1}, {0, 1}, {1, 0}, {1, 1}, {1, -1}};
        //获取行宽
        int rows = grid.length, colums = grid[0].length;
        //定义一个队列
        Deque<int[]> deque = new ArrayDeque<>();
        //将开始位置添加进队列尾部
        deque.addLast(new int[]{0, 0});
        grid[0][0] = 1;
        //第一层
        int count = 1;
        while (!deque.isEmpty()) {
            //上一层的元素个数
            int size = deque.size();
            //取出上一层所有的元素
            while (size-- > 0) {
                //从队列中头部取出一个元素，
                int[] poll = deque.poll();
                //走到终点
                if (poll[0] == rows - 1 && poll[1] == colums - 1) {
                    return count;
                }
                //往八个方向走一步，符合条件的话
                for (int[] direct : direction) {
                    int row = poll[0] + direct[0];
                    int colum = poll[1] + direct[1];
                    if (row < rows && row > -1 && colum < colums && colum > -1) {
                        //只走0的位置
                        if (grid[row][colum] == 0) {
                            deque.addLast(new int[]{row, colum});
                            //走过的地方不能再走
                            grid[row][colum] = 1;
                        }
                    }
                }
            }
            //上一步的元素，全部取完，走一步
            count++;
        }
        return -1;
    }

}
